#include "stdafx.h"



//#include <atlbase.h>
#include <oledbdm.h>

#include "DMMiningParameter.h"
using namespace PluginAlgorithms;


MiningParameter::MiningParameter(String ^ name, System::Type ^   type)
{
    m_fHasError				=	false;
	m_isExposed             =   true;
    m_isRequired            =   false;
    m_name                  =   name;
    m_type                  =   type;
    m_description           =   "";
    m_defaultValue          =   "";
    m_valueEnumeration      =   "";
    m_value                 =   nullptr;

    SetDbTypeNameFromType();

    // This is always 0 for now
    m_flags = 0;
}

MiningParameter::MiningParameter(String ^ name, 
                String ^ description, 
                String ^ defaultValue, 
                System::Boolean isRequired, 
                System::Boolean isExposed,
                System::Type ^   type)
{
	m_fHasError				=	false;
    m_isExposed             =   isExposed;
    m_isRequired            =   isRequired;
    m_name                  =   name;
    m_type                  =   type;
    m_description           =   description;
    m_defaultValue          =   defaultValue;
    m_valueEnumeration      =   "";
    m_value                 =   nullptr;

    SetDbTypeNameFromType();

    // This is always 0 for now
    m_flags = 0;
}

MiningParameter::MiningParameter(String ^ name, 
                String ^ description, 
                String ^ defaultValue, 
                String ^ valueEnumeration,
                System::Boolean isRequired, 
                System::Boolean isExposed,
                System::Type ^   type)
{
	m_fHasError				=	false;
    m_isExposed             =   isRequired;
    m_isRequired            =   isExposed;
    m_name                  =   name;
    m_type                  =   type;
    m_description           =   description;
    m_defaultValue          =   defaultValue;
    m_valueEnumeration      =   valueEnumeration;
    m_value                 =   nullptr;

    SetDbTypeNameFromType();

    // This is always 0 for now
    m_flags = 0;
}



void MiningParameter::SetDbTypeNameFromType()
{

	m_value                 =   nullptr;
    m_typeName              =   nullptr;

	if (m_type == DBNull::typeid)
	{
		m_typeName = gcnew String("DBTYPE_NULL");
	}
	else if (m_type == String::typeid)
	{
        m_typeName = gcnew String("DBTYPE_WSTR");
	}
	else if (m_type == Byte::typeid)
	{
        m_typeName = gcnew String("DBTYPE_I1");
	}
	else if (m_type == Int16::typeid)
	{
        m_typeName = gcnew String("DBTYPE_I2");
	}
	else if (m_type == Int32::typeid)
	{
        m_typeName = gcnew String("DBTYPE_I4");
	}
	else if (m_type == Int64::typeid)
	{
        m_typeName = gcnew String("DBTYPE_I8");
	}
	else if (m_type == UInt16::typeid)
	{
        m_typeName = gcnew String("DBTYPE_UI2");
	}
	else if (m_type == UInt32::typeid)
	{
        m_typeName = gcnew String("DBTYPE_UI4");
	}
	else if (m_type == UInt64::typeid)
	{
        m_typeName = gcnew String("DBTYPE_UI8");
	}
	else if (m_type == Single::typeid)
	{
        m_typeName = gcnew String("DBTYPE_R4");
	}
	else if (m_type == Double::typeid)
	{
        m_typeName = gcnew String("DBTYPE_R8");
	}
	else if (m_type == DateTime::typeid)
	{
        m_typeName = gcnew String("DBTYPE_DATE");
	}
	else if (m_type == Boolean::typeid)
	{
        m_typeName = gcnew String("DBTYPE_BOOL");
	}
	else
	{
        // TODO : add more explicit exception message
		m_description = gcnew System::String(L"ERROR: Parameter " ) + m_name + 
						gcnew System::String(L" has an invalid type: ") + m_type->ToString() ;
		m_typeName = gcnew String("DBTYPE_NULL");
		m_fHasError				=	true;
		m_name = gcnew System::String(L"ERROR: ") + m_name;
	}
}

void MiningParameter::ConvertRuntimeToVariant(IDMContextServices* in_pSvc, Object ^ value, VARIANT*  pVar)
{
	if (!value)
	{
		V_VT(pVar)  =   VT_NULL;
        return;
	}

    System::Type ^ mpType = value->GetType();

	if (mpType == DBNull::typeid)
	{
		V_VT(pVar)  =   VT_NULL;
	}
	else if (mpType == String::typeid)
	{
		String ^	rtString = value->ToString();

        V_VT(pVar)  =   VT_BSTR;
		V_BSTR(pVar) = (BSTR)(void*)System::Runtime::InteropServices::Marshal::StringToBSTR( rtString );
	}
	else if (mpType == Byte::typeid)
	{
		Byte^ pValue = dynamic_cast<Byte^>(value);
        V_VT(pVar) = VT_I1;
        V_I1(pVar) = *pValue;
	}
	else if (mpType == Int16::typeid)
	{
		Int16^ pValue = dynamic_cast<Int16^>(value);
        V_VT(pVar) = VT_I2;
        V_I2(pVar) = *pValue;
	}
	else if (mpType == Int32::typeid)
	{
		Int32^ pValue = dynamic_cast<Int32^>(value);
        V_VT(pVar) = VT_I4;
        V_I4(pVar) = *pValue;

	}
	else if (mpType == Int64::typeid)
	{
		Int64^ pValue = dynamic_cast<Int64^>(value);
        V_VT(pVar) = VT_I8;
        V_I8(pVar) = *pValue;

	}
	else if (mpType == UInt16::typeid)
	{
		UInt16^ pValue = dynamic_cast<UInt16^>(value);
        V_VT(pVar) = VT_UI2;
        V_UI2(pVar) = *pValue;

	}
	else if (mpType == UInt32::typeid)
	{
		UInt32^ pValue = dynamic_cast<UInt32^>(value);
        V_VT(pVar) = VT_UI4;
        V_UI4(pVar) = *pValue;

	}
	else if (mpType == UInt64::typeid)
	{
		UInt64^ pValue = dynamic_cast<UInt64^>(value);
        V_VT(pVar) = VT_UI8;
        V_UI8(pVar) = *pValue;

	}
	else if (mpType == Single::typeid)
	{
		Single^ pValue = dynamic_cast<Single^>(value);
        V_VT(pVar) = VT_R4;
        V_R4(pVar) = *pValue;

	}
	else if (mpType == Double::typeid)
	{
		Double^ pValue = dynamic_cast<Double^>(value);
        V_VT(pVar) = VT_R8;
        V_R8(pVar) = *pValue;
	}
	else if (mpType == DateTime::typeid)
	{
		DateTime^ pValue = dynamic_cast<DateTime^>(value);
        V_VT(pVar)  =   VT_DATE;
        V_DATE(pVar)    =   pValue->ToOADate();
	}
	else if (mpType == Boolean::typeid)
	{
		System::Boolean^ pValue = dynamic_cast<System::Boolean^>(value);
        V_VT(pVar) = VT_BOOL;
        V_BOOL(pVar) = *pValue;
    }
	else
	{
        // TODO : add more explicit exception message
		throw gcnew System::ArgumentException(mpType->ToString() );
	}

}


MiningParameter ^   MiningParameterCollection::default::get		( String ^ name )
{
    if( name != nullptr )
    {
        for( int nIndex = 0; nIndex < Count; nIndex ++ )
        {
            String ^    paramName = this[nIndex ]->Name;
            if( paramName != nullptr )
            {
                if( System::String::Compare( paramName,name ) == 0 )
                {
                    return dynamic_cast<MiningParameter ^>(this[nIndex]);
                }
            }
        }
    }
    return nullptr;
}